﻿using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.PB;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Coldairarrow.IBusiness;
using Coldairarrow.Entity.Base;

namespace Coldairarrow.Business.PB
{
    public partial class Bom_SubNodeBusiness : BaseBusiness<Bom_SubNode>, IBom_SubNodeBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        public Bom_SubNodeBusiness(IDbAccessor db, IOperator @operator)
            : base(db)
        {
            _operator = @operator;
        }

        #region 外部接口

       

        public async Task<PageResult<Bom_SubNodeDTO>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var search = input.Search;
            Expression<Func<Bom_SubNode,PB_Material, PB_MaterialType,Base_UnitGroup, Bom_SubNodeDTO>> select = (a, b,c,d) => new Bom_SubNodeDTO
            {
                Spec=b.Spec,
                Code=b.Code,
                ProductCode=c.Name,
                GroupName=d.Name,
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<PB_Material>() on a.MaterailId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<PB_MaterialType>() on b.MaterialTypeId equals c.Id into bc
                    from c in bc.DefaultIfEmpty()
                    join d in Db.GetIQueryable<Base_UnitGroup>() on b.UnitGroupId equals d.Id into bd
                    from d in bd.DefaultIfEmpty()
                    select @select.Invoke(a, b,c,d);
            if (!input.Search.Keyword.IsNullOrEmpty()) {
                q = q.Where(m=>m.ParentId==input.Search.Keyword);
            }
            return await q.GetPageResultAsync(input);
        }

        private List<string> GetItem(string ParentId, List<string> liststr, List<Bom_SubNode> listdata)
        {
            var itemlist = listdata.Where(x => x.ParentId == ParentId).ToList();
            foreach (var item in itemlist)
            {
                liststr.Add(item.Id);
                GetItem(item.Id, liststr, listdata);
            }
            return liststr;
        }

        public async Task<Bom_SubNode> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        public async Task AddDataAsync(Bom_SubNode data)
        {
            
            data.Deleted = false;
            await InsertAsync(data);
        }

        public async Task UpdateDataAsync(Bom_SubNode data)
        {
            await UpdateAsync(data);
        }

        public async Task DeleteDataAsync(List<string> ids)
        {
            var count = Db.GetIQueryable<Bom_SubNode>().Where(m=>ids.Contains(m.ParentId)).ToList();
            if (count.Count>0) {
                throw new BusException("请先删除子级");
            }
            await DeleteAsync(ids);
        }

        /// <summary>
        /// 递归查询树状bom元素
        /// </summary>
        /// <param name="ParentId"></param>
        /// <param name="ListData"></param>
        /// <returns></returns>
        public async Task<List<Bom_SubNodeTreeDTO>> GetItemTree(string ParentId, List<Bom_SubNodeTreeDTO> ListData)
        {
            var childrenItem = await Db.GetIQueryable<Bom_SubNode>().Where(x => x.ParentId == ParentId).ToListAsync();
            foreach (var item in childrenItem)
            {
                Bom_SubNodeTreeDTO treedata = new Bom_SubNodeTreeDTO();
                treedata.Id = item.Id;
                treedata.ParentId = item.ParentId;
                treedata.Text = item.MaterialName;
                treedata.Value = item.Id;
                ListData.Add(treedata);
                await GetItemTree(item.Id, ListData);
            }
            return ListData;
        }
        /// <summary>
        /// bom树形菜单
        /// </summary>
        /// <returns></returns>
        public async Task<List<Bom_SubNodeTreeDTO>> GetTreeBomListAsyncs()
        {
            var list = await Db.GetIQueryable<Bom_MainNode>().ToListAsync();
            List<Bom_SubNodeTreeDTO> listData = new List<Bom_SubNodeTreeDTO>();
            foreach (var item in list)
            {
                Bom_SubNodeTreeDTO tree = new Bom_SubNodeTreeDTO();
                tree.Id = item.Id;
                tree.Text = item.MaterialName;
                tree.Value = item.Id;
                listData.Add(tree);
                await GetItemTree(item.Id, listData);
            }
           
           
            var treeLists = listData
                .Select(x => new Bom_SubNodeTreeDTO
                {
                    Id = x.Id,
                    ParentId = x.ParentId,
                    Text = x.Text,
                    Value = x.Id,
                }).ToList();
          
            return TreeHelper.BuildTree(treeLists);
        }

        public async Task<List<treedto>> GetMaterialTypeListAsync(string ParentId,string Like)
        {
            List<treedto> listdata = new List<treedto>();
            if (ParentId.IsNullOrEmpty())
            {

                Expression<Func<Bom_MainNode, PB_Material, Base_UnitGroup, treedto>> select = (a, b,c) => new treedto
                {
                   Id=a.Id,
                   MaterialName=a.MaterialName+"("+ c.Name + ")",

                };
                select = select.BuildExtendSelectExpre();
                var q = from a in Db.GetIQueryable<Bom_MainNode>().AsExpandable()
                        join b in Db.GetIQueryable<PB_Material>() on a.MaterailId equals   b.Id into ab
                        from b in ab.DefaultIfEmpty()
                        join c in Db.GetIQueryable<Base_UnitGroup>() on b.UnitGroupId equals c.Id into bc
                        from c in bc.DefaultIfEmpty()
                        select @select.Invoke(a, b,c);

                if (!Like.IsNullOrEmpty()) {
                    q = q.Where(m=>m.MaterialName.Contains(Like));
                }
                listdata = q.ToList();
            }
            else
            {

                Expression<Func<Bom_SubNode, PB_Material, Base_UnitGroup, treedto>> select = (a, b,c) => new treedto
                {
                    Id = a.Id,
                    MaterialName = a.MaterialName + "(" + c.Name + ")",
                    ParentId=a.ParentId,
                  
                };
                select = select.BuildExtendSelectExpre();
                var q = from a in Db.GetIQueryable<Bom_SubNode>().AsExpandable()
                        join b in Db.GetIQueryable<PB_Material>() on a.MaterailId equals b.Id into ab
                        from b in ab.DefaultIfEmpty()
                        join c in Db.GetIQueryable<Base_UnitGroup>() on b.UnitGroupId equals c.Id into bc
                        from c in bc.DefaultIfEmpty()
                        select @select.Invoke(a, b,c);
                q = q.Where(m => m.ParentId == ParentId);
                listdata = q.ToList();
            }
            List<treedto> typelist = new List<treedto>();
            foreach (var item in listdata)
            {
                treedto typedata = new treedto();
                typedata.Id = item.Id;
                typedata.MaterialName = item.MaterialName;
                typedata.ParentId = item.ParentId;
                typelist.Add(typedata);
            }
            return  typelist;
        }


        #endregion

        #region 私有成员

        #endregion
    }
}